<template lang="pug">
  canvas(ref="canvasVerificationCode")
</template>

<script type="text/ecmascript-6">
export default {
  props: {
    canvasId: {
      type: String,
      default() {
        return `verifyCanvas_${Math.floor(Math.random() * (1000 - 1) + 1)}`
      }
    },
    value: {
      required: true,
      type: String,
      default: ''
    },
    width: {
      type: Number,
      default: 200
    },
    height: {
      type: Number,
      default: 80
    },
    type: {
      type: String,
      default: 'blend' // [letter]
    },
    interferingLine: {
      type: Boolean,
      default: true
    },
    interferingPoint: {
      type: Boolean,
      default: true
    },
    background: {
      type: String,
      default: ''
    },
    numberArray: {
      type: Array,
      default() {
        return '1,2,3,4,5,6,7,8,9,0'.split(',')
      }
    },
    letterArray: {
      type: Array,
      default() {
        return 'a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z'.split(',')
      }
    }
  },
  data() {
    return {
      code: ''
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.init()
      this.refresh()
    })
  },
  methods: {
    init() {
      let canvas = this.$refs.canvasVerificationCode
      canvas.id = this.canvasId
      canvas.width = this.width
      canvas.height = this.height
      canvas.innerHTML = '您的浏览器不支持CANVAS'
      canvas.style.cursor = 'pointer'
      let parent = this
      canvas.onclick = function () {
        parent.refresh()
      }
    },
    // 生成验证码
    refresh() {
      this.code = ''
      let ctx = null
      let canvas = this.$refs.canvasVerificationCode
      if (canvas.getContext) {
        ctx = canvas.getContext('2d')
      } else {
        return
      }

      ctx.textBaseline = 'middle'
      if (this.background !== '') {
        ctx.fillStyle = this.background
      } else {
        ctx.fillStyle = this.randomColor(180, 240)
      }

      ctx.fillRect(0, 0, this.width, this.height)

      let textArray = this.numberArray
      if (this.type === 'blend') {
        textArray.concat(this.letterArray)
      } else if (this.type === 'letter') {
        textArray = this.letterArray
      }

      for (let i = 1; i < 5; i++) {
        let _code = textArray[this.randomNum(0, textArray.length)]
        this.code += _code
        ctx.font = this.randomNum(this.height / 2, this.height) + 'px SimHei' // 随机生成字体大小
        ctx.fillStyle = this.randomColor(50, 160) // 随机生成字体颜色
        ctx.shadowOffsetX = this.randomNum(-3, 3)
        ctx.shadowOffsetY = this.randomNum(-3, 3)
        ctx.shadowBlur = this.randomNum(-3, 3)
        ctx.shadowColor = 'rgba(0, 0, 0, 0.3)'
        let x = this.width / 5 * i
        let y = this.height / 2
        let deg = this.randomNum(-30, 30)
        /** 设置旋转角度和坐标原点 **/
        ctx.translate(x, y)
        ctx.rotate(deg * Math.PI / 180)
        ctx.fillText(_code, 0, 0)
        /** 恢复旋转角度和坐标原点 **/
        ctx.rotate(-deg * Math.PI / 180)
        ctx.translate(-x, -y)
      }
      if (this.interferingLine) {
        /** 绘制干扰线 **/
        for (let i = 0; i < 4; i++) {
          ctx.strokeStyle = this.randomColor(40, 180)
          ctx.beginPath()
          ctx.moveTo(this.randomNum(0, this.width), this.randomNum(0, this.height))
          ctx.lineTo(this.randomNum(0, this.width), this.randomNum(0, this.height))
          ctx.stroke()
        }
      }
      if (this.interferingPoint) {
        /** 绘制干扰点 **/
        for (let i = 0; i < this.width / 4; i++) {
          ctx.fillStyle = this.randomColor(0, 255)
          ctx.beginPath()
          ctx.arc(this.randomNum(0, this.width), this.randomNum(0, this.height), 1, 0, 2 * Math.PI)
          ctx.fill()
        }
      }
    },
    /** 验证验证码 **/
    validate() {
      let _code = this.value.toLowerCase()
      let vCode = this.code.toLowerCase()
      if (_code === vCode) {
        return true
      } else {
        this.refresh()
        return false
      }
    },
    /* 生成一个随机数 */
    randomNum(min, max) {
      return Math.floor(Math.random() * (max - min) + min)
    },
    /* 生成一个随机色 */
    randomColor(min, max) {
      let r = this.randomNum(min, max)
      let g = this.randomNum(min, max)
      let b = this.randomNum(min, max)
      return 'rgb(' + r + ',' + g + ',' + b + ')'
    }
  }
}
</script>

<style scoped lang="stylus" rel="stylesheet/stylus">
</style>
